package br.com.firula.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;

import br.com.firula.bo.GenericBO;
import br.com.firula.threads.BreakSystem;
import br.com.firula.to.BaseTO;
import br.com.firula.util.Idiomas;
import br.com.firula.util.Paises;
import br.com.firula.web.filter.Filtro;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public abstract class GenericAction extends ActionSupport implements SessionAware, ServletRequestAware, ServletResponseAware{

	private static final long serialVersionUID = -6260695786062327455L;

	HttpServletResponse response;
	HttpServletRequest request;

	protected GenericBO mgr;
	protected BaseTO base;
	protected String id; 
	protected String cancel;
	protected String delete;
	protected List bases;
	protected Filtro filter;
	protected Map session;
	protected boolean newFiltro;
	protected String mensagem;
	
	protected String prefix;

	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}

	public HttpServletRequest getServletRequest() {
		return this.request;
	}

	public void setServletResponse(HttpServletResponse response) {
		this.response = response;
	}

	public HttpServletResponse getServletResponse() {
		return this.response;
	}

    public BaseTO getObject() {
        return base;
    }

    public void setObject(BaseTO base) {
        this.base = base;
    }
    
    public void setId(String id) {
        this.id = id;
    }
	
    public List getList() { 
        return bases; 
    }
	
    public void setCancel(String cancel) {
        this.cancel = cancel;
    }

    public void setDelete(String delete) {
        this.delete = delete;
    }

    
    public String delete() {
    	if (id != null) {
    		base = mgr.get(id.toString());
    		mgr.remove(id.toString());
    	} 
    	else
    		mgr.remove(base.getId().toString());
    	
        List args = new ArrayList();
        args.add(getPrefix());
        args.add(base.getAbreviation());
        ActionContext.getContext().getSession().put("message", 
                getText("crud.deleted", args));
                
        return "delete";
    }
    
    public String edit() {
        // check for an add
        if (id != null &&  !"".equals(id)) {
            base = mgr.get(id.toString());
        } else {
            base = getNew();
        }        
        return "input";
    }
    
    public String execute() {
        if (cancel != null) {
            return "cancel";
        }
        
        if (delete != null) {
            return delete();
        }
        
        return SUCCESS;
    }
    
    public String save() {
        mgr.save(base);
        List args = new ArrayList();
        args.add(getPrefix());
        args.add(base.getAbreviation());
        ActionContext.getContext().getSession().put("message", 
                getText("crud.saved", args));
          
        base = getNew();
        return "list";
    }
    
    public String list() { 
        Filtro f = (Filtro)session.get("FILTRO"); 
        
        //Mudando de entidade, filtro � anulado
        if(f!=null && !f.getClazz().equals(getNew().getClass())){
        	filter = null;
        	session.put("FILTRO", filter);
        }
        
        //Se filtro ja existe, ja vem filtrado, com o form preenchido
    	if(f!=null && f.getExample()!=null && f.getExample().length>0){
    		base = f.getExample()[0];
    	}
    	if(f!=null)
    		filter  = f;
    	
    	ActionContext.getContext().put("resultSize", 0);
    	
    	
        return SUCCESS; 
    }
    
    public String filter() {
    	if(!isNewFiltro()){
    		filter = (Filtro)session.get("FILTRO");
    		
    		if(filter != null && !filter.getClazz().equals(getNew().getClass())){
    			filter = null;
            }
    	}
    	if(filter==null){
        	filter = new Filtro();
        }
            	
        filter.setActionContext(ActionContext.getContext());
        filter.setClazz(getNew().getClass());
    	buildExample();
   		
    	if(isNewFiltro()){
   			filter.setExample(base);
   		}
   		session.put("FILTRO", filter);
	    bases = mgr.getList(filter);
        ActionContext.getContext().put("resultSize", mgr.getListCount(filter));
    	return "filter"; 
    }
    
    protected abstract BaseTO getNew();
    
    protected void buildExample(){
	   	if(base == null) {
    		base = getNew();  
    	}
	   	base.setRemovido(false);
    }
    
    protected String getPrefix(){
    	if (prefix == null) {
    		String[] parts = getClass().getName().split(".");
    		prefix = getClass().getName().substring(getClass().getName().lastIndexOf(".") + 1, getClass().getName().lastIndexOf("Action"));
    		prefix = prefix.toLowerCase();
    	}
    	return prefix; 
    }
    public Map getSession() {
		return session;
	}
	public void setSession(Map session) {
		this.session = session;
	}

	public boolean isNewFiltro() {
		return newFiltro;
	}

	public void setNewFiltro(boolean newFiltro) {
		this.newFiltro = newFiltro;
	}

	public Filtro getFilter() {
		return filter;
	}

	public void setFilter(Filtro filter) {
		this.filter = filter;
	}
	public HashMap getIdiomas(){
		return Idiomas.getIdiomas();
	}
	public HashMap<String,String> getPaises(){
		String lang = (String)session.get("LANG");
		if("en".equals(lang))
			return Paises.getPaisesEN();
		else if("es".equals(lang))
			return Paises.getPaisesES();
		else
			return Paises.getPaisesEN();
	}

	public String getMensagem() {
		return mensagem;
	}
	
	public void setMensagem(String mensagem) {
		this.mensagem = mensagem;
	}
	public boolean getDesativarFuncoesCriticas(){
		return BreakSystem.desativarFuncoesCriticas();
	}
}
